package com.campus.counseling.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.campus.counseling.entity.TestDimension;
import com.campus.counseling.entity.TestQuestion;
import com.campus.counseling.model.common.exception.ServiceException;
import com.campus.counseling.model.dto.TestDimensionDTO;
import com.campus.counseling.model.mapper.TestDimensionMapper;
import com.campus.counseling.model.query.TestDimensionQuery;
import com.campus.counseling.model.vo.TestDimensionVO;
import com.campus.counseling.model.vo.TestQuestionVO;
import com.campus.counseling.service.TestDimensionService;
import com.campus.counseling.service.TestQuestionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class TestDimensionServiceImpl extends ServiceImpl<TestDimensionMapper, TestDimension> implements TestDimensionService {

    private final TestQuestionService testQuestionService;

    @Override
    public Page<TestDimensionVO> list(TestDimensionQuery query) {
        Page<TestDimension> page = new Page<>(query.getPageNum(), query.getPageSize());
        
        // 使用自定义SQL查询，关联测试表获取测试标题
        Page<TestDimensionVO> voPage = baseMapper.selectDimensionVOPage(page, query);
        
        if (voPage.getRecords() != null) {
            log.info("查询到维度记录数: {}", voPage.getRecords().size());
        }
        
        return voPage;
    }

    @Override
    public TestDimensionVO getDimension(Long id) {
        TestDimension dimension = this.getById(id);
        return convertToVO(dimension);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createDimension(TestDimensionDTO dto) {
        TestDimension dimension = new TestDimension();
        BeanUtils.copyProperties(dto, dimension);
        this.save(dimension);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDimension(Long id, TestDimensionDTO dto) {
        TestDimension dimension = this.getById(id);
        if (dimension == null) {
            throw new ServiceException("维度不存在");
        }
        
        // 设置ID，防止被覆盖
        dto.setId(id);
        // 只复制需要更新的字段
        dimension.setDimensionKey(dto.getDimensionKey());
        dimension.setDimensionName(dto.getDimensionName());
        dimension.setDescription(dto.getDescription());
        dimension.setScoreRange(dto.getScoreRange());
        dimension.setWeight(dto.getWeight());
        dimension.setStatus(dto.getStatus());
        
        if (!this.updateById(dimension)) {
            throw new ServiceException("更新维度失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDimension(Long id) {
        this.removeById(id);
    }

    @Override
    public List<TestDimension> getDimensionsByTestId(Long testId) {
        log.info("获取测试维度, testId: {}", testId);
        return baseMapper.selectByTestId(testId);
    }

    @Override
    public TestDimension getDimensionByKey(Long testId, String dimensionKey) {
        LambdaQueryWrapper<TestDimension> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TestDimension::getTestId, testId)
                   .eq(TestDimension::getDimensionKey, dimensionKey);
        return getOne(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchCreateDimensions(List<TestDimension> dimensions) {
        return saveBatch(dimensions);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDimension(TestDimension dimension) {
        return updateById(dimension);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteDimension(Long testId, String dimensionKey) {
        LambdaQueryWrapper<TestDimension> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TestDimension::getTestId, testId)
                   .eq(TestDimension::getDimensionKey, dimensionKey);
        return remove(queryWrapper);
    }

    @Override
    public Map<String, Integer> getDimensionQuestionCount(Long testId) {
        // 获取测试的所有维度
        List<TestDimension> dimensions = getDimensionsByTestId(testId);
        if (dimensions.isEmpty()) {
            return new HashMap<>();
        }

        // 获取维度键列表
        List<String> dimensionKeys = dimensions.stream()
                .map(TestDimension::getDimensionKey)
                .collect(Collectors.toList());

        // 获取每个维度的问题数量
        Map<String, Integer> countMap = new HashMap<>();
        for (String dimensionKey : dimensionKeys) {
            List<TestQuestion> questions = getQuestionsByDimension(testId, dimensionKey);
            countMap.put(dimensionKey, questions.size());
        }

        return countMap;
    }

    @Override
    public List<TestQuestion> getQuestionsByDimension(Long testId, String dimension) {
        List<TestQuestionVO> questionVOs = testQuestionService.getQuestionsByDimension(testId, dimension);
        return questionVOs.stream()
                .map(this::convertToEntity)
                .collect(Collectors.toList());
    }

    private TestQuestion convertToEntity(TestQuestionVO vo) {
        if (vo == null) {
            return null;
        }
        TestQuestion entity = new TestQuestion();
        BeanUtils.copyProperties(vo, entity);
        return entity;
    }

    private Page<TestDimensionVO> convertToVOPage(Page<TestDimension> page) {
        Page<TestDimensionVO> voPage = new Page<>();
        BeanUtils.copyProperties(page, voPage, "records");
        
        List<TestDimensionVO> voList = page.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        
        voPage.setRecords(voList);
        return voPage;
    }

    private TestDimensionVO convertToVO(TestDimension dimension) {
        if (dimension == null) {
            return null;
        }
        TestDimensionVO vo = new TestDimensionVO();
        BeanUtils.copyProperties(dimension, vo);
        return vo;
    }
} 